package com.sample.snl.frontend.LexicalAnalysis;

import java.io.IOException;
import java.io.Reader;

public class Automaton {
    StringBuilder stringBuilder;
    State state;
    Reader reader;
    Token token;
    boolean gotToken = false;
    State StartState;
    State InNumState;
    State InIdState;
    State InCommentState;
    State InCharState;
    State ErrorState;
    State InAssignState;
    State InRangeState;
    State InDotState;

    public Automaton(Reader reader) {
        this.stringBuilder = new StringBuilder();
        this.StartState = new StartState(this);
        this.InIdState = new InIdState(this);
        this.InNumState = new InNumState(this);
        this.InAssignState = new InAssignState(this);
        this.InCharState = new InCharState(this);
        this.InRangeState = new InRangeState(this);
        this.InDotState = new InDotState(this);
        this.ErrorState = new ErrorState(this);
        this.InCommentState = new InCommentState(this);
        this.reader = reader;
        this.token = new Token();
        this.state = this.StartState;
    }


    public void setState(State state) {
        this.state = state;
    }


    public int getChar() throws IOException {
        int ch;
        if (LexicalAnalyser.getMeFirst != -1 && LexicalAnalyser.getMeFirst != ' ' && LexicalAnalyser.getMeFirst != '\r' && LexicalAnalyser.getMeFirst != '\n') {
            ch = LexicalAnalyser.getMeFirst;
            LexicalAnalyser.getMeFirst = -1;
        } else ch = reader.read();

        if (ch == '\n') {
            LexicalAnalyser.column = 0;
            LexicalAnalyser.line++;
        } else if (ch != -1) LexicalAnalyser.column++;

        if (ch == '\r') LexicalAnalyser.column--;
        //LexicalAnalyser.LOG.trace("The current character is {}({})[{}:{}]", displayChar(ch), ch, LexicalAnalyser.line, LexicalAnalyser.column);
        return ch;
    }

    public void unGetChar(int ch) {
        LexicalAnalyser.getMeFirst = ch;
        LexicalAnalyser.column--;
    }

    public boolean isAlphabetic(int ch) {
        return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
    }

    public boolean isDigit(int ch) {
        return (ch >= '0' && ch <= '9');
    }

    public boolean isBlank(int ch) {
        return ((char) ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
    }

    public String displayChar(int ch) {
        if (ch == '\n') return "\\n";
        else if (ch == '\r') return "\\r";
        else return "" + (char) ch;
    }
}
